<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2021/02/08
 * Time: 13:29
 * @link http://www.lmterp.cn
 */

namespace app\admin\controller\wms;

use app\admin\controller\BaseController;
use app\common\library\Tools;
use app\common\model\JobFlowModule;
use app\common\model\WarehouseCheck;
use app\common\model\WarehouseStock;
use app\common\model\WarehouseTerpInfo;
use app\common\service\product\StockService;
use app\common\service\product\WarehouseService;
use think\Db;
use think\facade\Validate;

/**
 * 盘点库存
 * Class Stock
 * @package app\admin\controller\wms
 */
class WcheckController extends BaseController
{
    protected $moduleName = 'warehouse_check';

    /**
     * 库存列表
     * @return string
     * @date 2021/02/08
     * @author longli
     */
    public function index()
    {
        if($this->request->isAjax())
        {
            $check = WarehouseCheck::order("check_id desc")
                ->where('warehouse_id', $this->warehouse->warehouse_id);
            $this->searchModel($check, [
                'eq' => ['status', 'check_sn', 'check_status'],
                'times' => ['check_date', 'finish_date']
            ]);
            $limit = $this->getPageSize();
            $check = $check->paginate($limit);
            $this->assign('is_show_check', $this->user->hasPermissions('/wms/wcheck/check'));
            $this->assign('is_show_take', $this->user->hasPermissions('/wms/wcheck/take'));
            $this->assign('is_show_save', $this->user->hasPermissions('/wms/wcheck/save'));
            $this->assign('is_show_info', $this->user->hasPermissions('/wms/wcheck/info'));
            $this->assign("list", $check->getCollection());
            $this->assign("page", $check->render());
            return $this->fetch('lists');
        }
        $this->assign('check_status', JobFlowModule::$CHECK_STATUS);
        $this->assign('status', ['待盘点', '已盘点']);
        return $this->fetch('index');
    }

    /**
     * 创建盘点单
     * @date 2021/02/09
     * @author longli
     */
    public function add()
    {
        $checkId = $this->request->get('check_id');
        if(!empty($checkId)) $this->assign('check', WarehouseCheck::get($checkId));
        return $this->fetch('add');
    }

    /**
     * 保存盘点单
     * @date 2021/02/09
     * @author longli
     */
    public function save()
    {
        $this->validateSave();
        if($this->request->isPost())
        {
            $vis = ['check_date', 'finish_date', 'status', 'remark', 'check_id'];
            $data = ['warehouse_id' => $this->warehouse->warehouse_id]
                + $this->request->only($vis, 'post');
            if(!empty($data['status'])) $data['finish_date'] = Tools::now();
        }
        else
        {
            $data = $this->request->only(['check_id', 'status'], 'get');
            if($data['status'] == WarehouseCheck::IS_YES) $data['finish_date'] = Tools::now();
        }
        WarehouseService::getInstance()->addCheck($data)
            ? $this->success('操作成功')
            : $this->error('操作失败');
    }

    /**
     * 验证创建盘点单
     * @return bool|string
     * @date 2021/02/09
     * @author longli
     */
    private function validateSave()
    {
        if($this->request->isPost())
        {
            $validate = Validate::make([
                'check_date'  => 'require|date',
            ],[
                'check_date.require' => '盘点日期必填',
                'check_date.date' => '盘点日期有误',
            ]);
            $data = $this->request->post();
        }
        else if($this->request->isGet())
        {
            $validate = Validate::make([
                'check_id'  => 'require',
                'status'  => 'require|integer',
            ],[
                'check_id.require' => '非法请求',
                'status.require' => '盘点状态必填',
                'status.integer' => '盘点状态只能是数字',
            ]);
            $data = $this->request->only(['check_id', 'status'], 'get');
        }
        if(!$validate->batch()->check($data)) $this->error(join(', ', $validate->getError()));
        $checkId = $this->request->request('check_id');
        if(!empty($checkId))
        {
            $check = WarehouseCheck::get($checkId);
            if(empty($check)) $this->error('盘点单不存在');
            if($check->status == WarehouseCheck::IS_YES && !empty($check->finish_date))
                $this->error("盘点单【{$check->check_sn}】已完成，不能修改");
        }
    }

    /**
     * 盘点
     * @date 2021/02/09
     * @author longli
     */
    public function take()
    {
        // 加载盘点列表
        if($this->request->isAjax())
        {
            $stock = WarehouseStock::order("stock_id desc");
            $stock->whereIn("warehouse_id", $this->request->request('warehouse_id'));
            $skus = $this->request->request('sku', '', 'trim');
            if(!empty($skus))
            {
                $skus = replaceStr($skus);
                $s = \app\common\model\Product::getSkusBySpu(replaceStr($skus));
                $stock->whereIn('sku', !empty($s) ? $s : $skus);
            }
            $limit = $this->getPageSize();
            $stock = $stock->paginate($limit);
            $this->assign("list", $stock->getCollection());
            $this->assign("page", $stock->render());
            return $this->fetch('take_lists');
        }
        $this->validateTake();
        // 显示页面
        $this->assign('page_size', 300);
        $this->assign('check', WarehouseCheck::get($this->request->get('check_id')));
        return $this->fetch('take');
    }

    /**
     * 执行盘点
     * @date 2021/02/15
     * @author longli
     */
    public function take_save()
    {
        $this->validateTake();
        $data = $this->request->post();
        $check = WarehouseCheck::get($data['check_id']);
        if(empty($check)) $this->error('盘点单不存在');
        try
        {
            Db::startTrans();
            foreach($data['sku'] as $k => $sku)
            {
                if(($msg = StockService::checkStock($check, $sku, $data['stock_ing'][$k], $data['remark'][$k])) !== true)
                {
                    Db::rollback();
                    $this->error($msg);
                }
            }
            Db::commit();
            $this->success('盘点成功');
        }catch (\think\exception\DbException $e)
        {
            Db::rollback();
            $this->error('盘点失败');
        }
    }

    public function info()
    {
        $cid = $this->request->get('check_id');
        if(empty($cid)) $this->error('非法请求');
        $check = WarehouseCheck::get($cid);
        if(empty($check)) $this->error('盘点单不存在');
        $this->assignCheck($cid);
        $this->assign('check', $check);
        $this->assign("check_info", $this->renderTerp(WarehouseCheck::class, $check->check_id, "wms/warehouse/terp/check_info"));
        return $this->fetch('info');
    }

    /**
     * 验证盘点单详情
     * @return bool|string
     * @date 2021/02/09
     * @author longli
     */
    private function validateTake()
    {
        if($this->request->isPost())
        {
            $validate = Validate::make([
                'check_id'  => 'require',
                'warehouse_id'  => 'require',
                'sku'  => 'require|array',
                'stock_ing'  => 'require|array',
            ],[
                'check_id.require' => '非法请求',
                'warehouse_id.require' => '仓库必选',
                'sku.require' => '盘点SKU必填',
                'sku.array' => '盘点SKU数据格式错误',
                'stock_ing.require' => '盘点数量必填',
                'stock_ing.array' => '盘点数量数据格式错误',
            ]);
            $data = $this->request->post();
            if(!$validate->batch()->check($data))$this->error(join(', ', $validate->getError()));
            $error = [];
            // 验证数量
            foreach($data['stock_ing'] as $k => $v)
            {
                if($v < 0) $error[] = "SKU【{$data[$k]['sku']}】盘点数量不能小于0";
            }
            if(!empty($error)) $this->error(join(', ', $error));
        }
        else if($this->request->isGet())
        {
            $checkId = $this->request->get('check_id');
            if(empty($checkId)) $this->error('非法请求');
            $check = WarehouseCheck::get($checkId);
            if(empty($check)) $this->error('盘点单不存在');
            if(!JobFlowModule::isCheckFinish($check)) $this->error("盘点单【{$check->check_sn}】未审批通过");
            if($check->status == WarehouseCheck::IS_YES && !empty($check->finish_date))
                $this->error('盘点单已完成');
        }
    }

    /**
     * 盘点日志
     * @date 2021/06/18
     * @author longli
     */
    public function log()
    {
        if($this->request->isAjax())
        {
            $terp = WarehouseTerpInfo::with(['warehouse', 'check', 'admin'])
                ->where([
                    ["id_type", 'eq', WarehouseCheck::getTable()],
                    ["warehouse_id", 'eq', $this->warehouse->warehouse_id]
                ])
                ->order("info_id desc");
            $this->searchModel($terp, [
                'eq' => ['check_id' => 'ref_id', 'warehouse_id']
            ]);
            $limit = $this->getPageSize();
            $terp = $terp->paginate($limit);
            $this->assign("list", $terp->getCollection());
            $this->assign("page", $terp->render());
            return $this->fetch('log_lists');
        }
        $this->assign('checks', WarehouseCheck::field(['check_id', 'check_sn'])
            ->where("warehouse_id", $this->warehouse->warehouse_id)
            ->order("check_id desc")
            ->select());
        return $this->fetch('log');
    }
}